package com.casa.POI.dianping;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Property;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;


public class FetchPageUrlsExecutor extends CityThreadsExecutor {
	
	public FetchPageUrlsExecutor(int cityId) {
		super(cityId);
	}
	
	class Workitem implements Runnable {
		private SearchUrl searchUrl;

		public Workitem(SearchUrl searchUrl) {
			this.searchUrl = searchUrl;
		}

		@Override
		public void run() {
			String searchUrlStr = searchUrl.getUrl();
			int totalPage = 0;
			
			try {
				totalPage = fetchTotalPage(searchUrlStr);
			} catch (Exception e) {
				Console.writeLine(searchUrlStr);
				e.printStackTrace();
				return;
			}
			
			Session s = SessionManager.getInstance().openSession();
			s.beginTransaction();
			
			searchUrl.setTotalPage(totalPage);
			s.update(searchUrl);
			
			for (int i = 1; i <= totalPage; i++) {
				String pageUrlStr = String.format("%sp%d", searchUrlStr, i);
				PageUrl pu = new PageUrl(pageUrlStr, searchUrlStr, getCityId());
				s.save(pu);
			}
			
			s.getTransaction().commit();
			s.close();
			
			printStatus(searchUrlStr);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected List<? extends Runnable> getNextBatchWorks() {
		Session s = SessionManager.getInstance().openSession();
		Criteria c = s.createCriteria(SearchUrl.class);
		c.add(Property.forName("totalPage").isNull());
		c.add(Property.forName("cityId").eq(getCityId()));
		c.setMaxResults(ConfigurationManager.getInstance().getBatchSize());
		List<SearchUrl> searchUrls = c.list();
		s.close();
		List<Workitem> works = new ArrayList<Workitem>();
		for (SearchUrl searchUrl : searchUrls) {
			works.add(new Workitem(searchUrl));
		}
		return works;
	}
	
	public int fetchTotalPage(String url) throws IOException, XPatherException {
		TagNode node = SpiderUtil.cleanUrl(url);
		Object[] results = node.evaluateXPath("//div[@class='Pages']");
		if (results.length == 0) {
			results = node.evaluateXPath("//div[@class='noResult']");
			return 1 - results.length;
		} else {
			TagNode pagesNode = (TagNode) results[0];
			results = pagesNode.evaluateXPath("//a[@class='PageLink']");
			TagNode lastPageNode = (TagNode) results[results.length - 1];
			String title = lastPageNode.getAttributeByName("title");
			return Integer.parseInt(title);
		}
	}
	
}
